今天兩個章節寫在一起,因為兩個份量都算較少,首先我們來分享Day21的章節。
此章節功能是利用Geolocation API,取得我們目前位置的經緯度、方向、速度
等等,如下圖,當我們在移動時,會顯示我們的移動速度,且座標會依我們的移動方向做轉動,而由於隱私權關係,在使用前依然會詢問我們是否要開啟location,而此功能在Web裝置上較不常用,大多是使用在手機裝置上。
此處用到兩個屬性:
coords.heading
:目前前進方向的角度,以北方為0度順時針計算。
coords.speed
:目前的速度(公尺/秒)。
<script>
const arrow = document.querySelector('.arrow');
const speed = document.querySelector('.speed-value');
// navigator.geolocation.getCurrentPosition((position))
// let watch = navigator.geolocation.watchPosition((data)
let watch = navigator.geolocation.watchPosition((data) => {
console.log(data);
speed.textContent = data.coords.speed;
arrow.style.transform = `rotate(${data.coords.heading}deg)`;
}, (err) => {
console.error(err);
navigator.geolocation.clearWatch(watch);
});
</script>
再來是Day22的部分,此章節要達到的功能就是當我們滑鼠移入至a標籤的字時,會對其字動態反白及一些樣式,而我們在這邊也分為區域性的移入樣式套用,及全域性的。
首先,我們在html部分新增一個span以來增添樣式至我們移入的字上。
<nav>
<ul class="menu">
<!-- 設置一個highlight去將樣式套在我們滑鼠所移至的字 -->
<span class="highlight"></span>
<li><a href="">Home</a></li>
<li><a href="">Order Status</a></li>
<li><a href="">Tweets</a></li>
<li><a href="">Read Our History</a></li>
<li><a href="">Contact Us</a></li>
</ul>
</nav>
在js部分,我們獲取所有在menu標籤為a的字,還有要反白的樣式span,並且將我們樣式先做隱藏。
let target = document.querySelectorAll('.menu a');
let highlight = document.querySelector('span');
highlight.style.display = "none";
再來,對我們的字增添滑鼠移入的事件及函數。
target.forEach((e) => {
e.addEventListener('mouseenter', enterHandler)
})
當滑鼠移入時做函數處理,獲取當前移入字的位置、寬度、高度等,並利用style直接寫入,注意當我們滾動畫面時,因為top,left是以當前整個頁面的位置去做計算
,因此會跑版
,所以我們要改利用offsetTop/Left
來獲取當前視窗離上面及左邊的距離,這樣即不會造成跑版。
function enterHandler(e) {
console.log(this.getBoundingClientRect());
// DOMRect {x: 263.9750061035156, y: 100, width: 52.6875, height: 28.399999618530273, top: 100, …}
let {
width,
height,
top,
left
} = this.getBoundingClientRect();
highlight.style.display = "";
highlight.style.width = width + "px";
highlight.style.height = height + "px";
// highlight.style.top = top + "px";
// highlight.style.left = left + "px";
// 假如滾動頁面,利用offset就不會跑掉
highlight.style.top = this.offsetTop + "px";
highlight.style.left = this.offsetLeft + "px";
}
而當我們想為全部a標籤的字做移入的處理,且在做視窗大小調整時,也不會跑版,首先要將我們的span移入至外層。
<nav>
<!-- 設置一個highlight去將樣式套在我們滑鼠所移至的字 -->
<span class="highlight"></span>
<ul class="menu">
<li><a href="">Home</a></li>
<li><a href="">Order Status</a></li>
<li><a href="">Tweets</a></li>
<li><a href="">Read Our History</a></li>
<li><a href="">Contact Us</a></li>
</ul>
</nav>
接著在js部分,我們新增一個now用來記錄當前指向的字。
let now = null;
let target = document.querySelectorAll('a');
let highlight = document.querySelector('span');
highlight.style.display = "none";
再來,我們對視窗大小的調整增添事件函數處理。
// 當調整視窗大小時觸發,做RWD也能不跑版
window.addEventListener('resize', setPosition)
target.forEach((e) => {
e.addEventListener('mouseenter', enterHandler)
})
而滑鼠移入的事件函數處理,當我們移入時,就將當前的字this紀錄至now,並呼叫套用樣式的函數。
function enterHandler() {
// 紀錄當前移入的字
now = this;
setPosition();
}
我們將套用樣式的函數,封裝起來做字位置及相關資料獲取,而在滾動頁面時,我們在top,left部分加上window.scrollY/X,也就是當前滾動的距離
,這樣即可達到不會跑版的效果。
function setPosition() {
// 如果沒有移入字就跳出
if (!now) return
let {
width,
height,
top,
left
} = now.getBoundingClientRect();
highlight.style.display = "";
highlight.style.width = width + "px";
highlight.style.height = height + "px";
// Window.scrollY / scrollX
// 返回視窗在垂直/水平方向已滾動的像素值
// 假如滾動頁面,利用原本的座標位置,再加上scrollX/Y就不會跑掉
highlight.style.top = top + window.scrollY + "px";
highlight.style.left = left + window.scrollX + "px";
}